﻿using System.Drawing;

namespace GeoSketch2.Core
{
    /// <summary>
    /// The GeoPoint2D object, has 2D double coordinates
    /// </summary>
    public class Point2D : BaseDrawableObject
    {
        #region Fields
        /// <summary>
        /// The location of the point
        /// </summary>
        public Point2D64D Point;
        #endregion

        #region Constructor

        /// <summary>
        /// A point with 2D coordinates
        /// </summary>
        /// <param name="Point">The location of the point</param>
        public Point2D(Point2D64D Point)
            : this(Point, new Layer())
        {
        }

        /// <summary>
        /// A point with 2D coordinates
        /// </summary>
        /// <param name="Point">The location of the point</param>
        /// <param name="Layer">The layer of the point</param>
        public Point2D(Point2D64D Point, Layer Layer)
            : this(Point, Layer, ColorByLayer())
        {
        }

        /// <summary>
        /// A point with 2D coordinates
        /// </summary>
        /// <param name="Point">The location of the point</param>
        /// <param name="Layer">The layer of the point</param>
        /// <param name="Color">The color of the point</param>
        public Point2D(Point2D64D Point, Layer Layer, Color Color)
            : base(Layer, Color, LineTypeByLayer())
        {
            this.Point = Point;
        }
        #endregion

        #region Methods
        /// <summary>
        /// Draws the point if unselected
        /// </summary>
        /// <param name="Viewport">The viewport to draw to</param>
        protected override void DrawUnselected(BaseViewport Viewport)
        {
            DrawCustomPen(Viewport, Pen);
        }

        /// <summary>
        /// Draws the point if unselected
        /// </summary>
        /// <param name="Viewport">The viewport to draw to</param>
        protected override void DrawSelected(BaseViewport Viewport)
        {
            DrawCustomPen(Viewport, Vars.Setup.Tools.TSelection.SelectionPen);
        }

        /// <summary>
        /// Draws the point with a custom pen
        /// </summary>
        /// <param name="Viewport">The viewport to draw to</param>
        /// <param name="CustomPen">The pen to draw with</param>
        public override void DrawCustomPen(BaseViewport Viewport, Pen CustomPen)
        {
            Point2D64D Point_screen = Viewport.Object2ImageTransformation.Transform(Point);
            Viewport.Graphic.DrawLine(CustomPen, Point_screen, Point_screen + new Point2D64D(-Vars.Setup.DrawableObjects.Point2D.CrossRadius, -Vars.Setup.DrawableObjects.Point2D.CrossRadius));
            Viewport.Graphic.DrawLine(CustomPen, Point_screen, Point_screen + new Point2D64D(Vars.Setup.DrawableObjects.Point2D.CrossRadius, -Vars.Setup.DrawableObjects.Point2D.CrossRadius));
            Viewport.Graphic.DrawLine(CustomPen, Point_screen, Point_screen + new Point2D64D(-Vars.Setup.DrawableObjects.Point2D.CrossRadius, Vars.Setup.DrawableObjects.Point2D.CrossRadius));
            Viewport.Graphic.DrawLine(CustomPen, Point_screen, Point_screen + new Point2D64D(Vars.Setup.DrawableObjects.Point2D.CrossRadius, Vars.Setup.DrawableObjects.Point2D.CrossRadius));


            if (Vars.Setup.DrawableObjects.Point2D.DrawId)
            {
                Viewport.Graphic.DrawString(Id.ToString(),
                    Vars.Setup.DrawableObjects.Point2D.IdFont,
                    CustomPen.Brush,
                    Viewport.Object2ImageTransformation.Transform(Point) + new Point2D64D(Vars.Setup.DrawableObjects.Point2D.CrossRadius + 1, Vars.Setup.DrawableObjects.Point2D.CrossRadius + 1));
            }
        }

        /// <summary>
        /// The method to test if the GeoPoint is near to the point clicked, for an object selection purpose
        /// </summary>
        /// <param name="Clic">The point clicked in object coordinates</param>
        /// <param name="IsNearDistance">The distance under which the clic is near to the object</param>
        public override bool IsNear(Point2D64D Clic, double IsNearDistance)
        {
            double distance = Clic.Distance2D(Clic);

            if (distance < IsNearDistance)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Returns the nearest point to the click, null if none
        /// </summary>
        /// <param name="Clic">The point clicked in object coordinates</param>
        /// <param name="IsNearDistance">The distance under which the clic is near to the object</param>
        public override Point2D64D NearestPoint(Point2D64D Clic, double IsNearDistance)
        {
            if (IsNear(Clic, IsNearDistance))
            {
                return Point;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Clones the object
        /// </summary>
        public override T Clone<T>()
        {
            object o = new Point2D((Point2D64D)Point.DeepClone(), Layer, Color);
            return (T)o;
        }

        /// <summary>
        /// Translates the object
        /// </summary>
        /// <param name="Vector">The translation vector</param>
        public override void Translate(Point2D64D Vector)
        {
            Point.X += Vector.X;
            Point.Y += Vector.Y;
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets the bounding box of the object, the Y-axis direction of the REctangleD must be upside
        /// </summary>
        public override RectangleD Bounds
        {
            get
            {
                return RectangleD.FromCenter(Point, 1, 1, YAxisDirection.UpSide);
            }
        } 
        #endregion
    }
}
